package com.jsyso.jsyso.util.jcollect;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.jsyso.jsyso.util.Callback;
import com.jsyso.jsyso.util.JsMap;

/**
 * Map过滤工具类
 * @author janjan, xujian_jason@163.com
 *
 * @param <K> Key类型
 * @param <V> Value类型
 */
public class JMap<K, V> {

	// map数据
	private Map<K, V> data;
	
	/**
	 * 初始化构建新对象
	 */
	@SuppressWarnings("unchecked")
	public JMap(Map<K, V> data) {
		if(data != null) {
			try {
				this.data = data.getClass().newInstance();
			} catch (Exception e) {
				this.data = new HashMap<K, V>();
			}
			this.data.putAll(data);
		}
	}
	
	/**
	 * 集合是否为空
	 * @return
	 */
	public boolean dataIsEmpty() {
		return data == null || data.isEmpty();
	}
	
	/**
	 * 包含keys
	 * @param keys
	 * @return
	 */
	public JMap<K, V> include(Object... keys) {
		if(!dataIsEmpty()) {
			List<K> dataKeys = new ArrayList<K>(this.data.keySet());
			dataKeys.removeAll(Arrays.asList(keys));
			this.exclude(dataKeys.toArray());
		}
		return this;
	}
	
	/**
	 * 不包含keys
	 * @param keys
	 * @return
	 */
	public JMap<K, V> exclude(Object... keys) {
		if(!dataIsEmpty()) {
			for(Object key : keys) {
				this.data.remove(key);
			}
		}
		return this;
	}
	
	/**
	 * 处理那些Key
	 * @param callback
	 * @param keys
	 * @return
	 */
	public JMap<K, V> handle(Callback<V, V> callback, K... keys) {
		if(!dataIsEmpty()) {
			for(int i=0; callback!=null && i<keys.length; ++i) {
				K key = keys[i];
				V value = callback.handle(this.data.get(key));
				if(value == null) {
					this.data.remove(key);
				}else {
					this.data.put(key, value);
				}
			}
		}
		return this;
	}
	
	/**
	 * 重命key名
	 * @param keyname 旧名
	 * @param rename 新名
	 * @return
	 */
	public JMap<K, V> rename(K keyname, K rename) {
		if(!dataIsEmpty() 
				&& keyname != null && rename != null) {
			V value = this.data.get(keyname);
			this.data.put(rename, value);
			this.data.remove(keyname);
		}
		return this;
	}
	
	/**
	 * 重命所有key名
	 */
	public JMap<K, V> renameAll(Callback<K, K> callback) {
		if(!dataIsEmpty()) {
			Set<K> keys = new HashSet<K>(this.data.keySet());
			List<K> deleteKeys = new ArrayList<K>(keys.size());
			for(K key : keys) {
				K newKey = callback.handle(key);
				if(!key.equals(newKey)) {
					this.data.put(newKey, this.data.get(key));
					deleteKeys.add(key);
				}
			}
			for(K key : deleteKeys) {
				this.data.remove(key);
			}
		}
		return this;
	}
	
	/**
	 * 返回data
	 * @return
	 */
	public Map<K, V> end() {
		return this.data;
	}
	
	/**
	 * 如确定begin(JsMap)传入的为JsMap，
	 * 可调用此方法强制转成JsMap
	 * @return
	 */
	public JsMap jsEnd() {
		return (JsMap) this.data;
	}
}
